﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices; // 用于调用系统API（热键）
using System.Windows.Forms;

namespace QuickScreenshot
{
    public partial class FrmMain : Form
    {
        #region 注册/取消热键的系统API
        // 注册/取消热键的系统API
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        #endregion

        #region 热键ID
        // 热键ID（自定义，只要唯一即可）
        private const int HOTKEY_ID = 1001;
        // PrintScreen键的虚拟键码（固定值0x2C）
        private const int VK_PRINTSCREEN = 0x2C;
        #endregion

        #region 保存路径
        // 保存路径（默认：我的图片\Screenshots）
        private readonly string defaultSavePath;
        #endregion

        #region 主窗体初始化
        /// <summary>
        /// 主窗体初始化
        /// </summary>
        public FrmMain()
        {
            InitializeComponent();
            // 初始化默认路径
            defaultSavePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Screenshots");
            txtSavePath.Text = defaultSavePath;

            // 初始化图片格式下拉框
            cboImageFormat.SelectedIndex = 0; // 默认选第一项（PNG）

            // 注册热键（窗口加载时）
            RegisterHotKey(Handle, HOTKEY_ID, 0, VK_PRINTSCREEN);
        } 
        #endregion

        #region 单击浏览按钮
        /// <summary>
        /// 单击浏览按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dialog = new FolderBrowserDialog())
            {
                dialog.Description = "选择截屏保存路径";
                dialog.SelectedPath = txtSavePath.Text; // 默认显示当前路径

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    txtSavePath.Text = dialog.SelectedPath; // 更新路径为用户选择的文件夹
                }
            }
        }
        #endregion

        #region 重写窗口消息处理，监听热键
        /// <summary>
        /// 重写窗口消息处理，监听热键
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            // 热键消息的标识是0x0312
            if (m.Msg == 0x0312 && m.WParam.ToInt32() == HOTKEY_ID)
            {
                // 按下了PrintScreen，执行截屏+保存
                CaptureAndSave();
            }
        }
        #endregion

        #region 截取屏幕保存图片的方法
        /// <summary>
        /// 截取屏幕保存图片的方法
        /// </summary>
        private void CaptureAndSave()
        {
            try
            {
                // 1. 获取屏幕尺寸（支持单显示器，多显示器可扩展）
                Rectangle screenRect = Screen.PrimaryScreen.Bounds;

                // 2. 创建与屏幕同尺寸的位图（用于存储截屏内容）
                using (Bitmap screenshot = new Bitmap(screenRect.Width, screenRect.Height))
                {
                    // 3. 从屏幕捕获图像到位图
                    using (Graphics g = Graphics.FromImage(screenshot))
                    {
                        // 从屏幕左上角(0,0)开始，捕获整个屏幕到位图
                        g.CopyFromScreen(screenRect.Left, screenRect.Top, 0, 0, screenRect.Size);
                    }

                    // 4. 准备保存路径和文件名（用时间戳避免重名）
                    string saveFolder = txtSavePath.Text;
                    Directory.CreateDirectory(saveFolder); // 确保文件夹存在（不存在则创建）

                    string fileName = $"screenshot_{DateTime.Now:yyyyMMddHHmmssfff}"; // 精确到毫秒，避免重名
                    string fileExt = cboImageFormat.Text.ToLower(); // 格式（png/jpg）
                    string fullPath = Path.Combine(saveFolder, $"{fileName}.{fileExt}");

                    // 5. 保存图片（根据选择的格式）
                    ImageFormat format = fileExt == "png" ? ImageFormat.Png : ImageFormat.Jpeg;
                    screenshot.Save(fullPath, format);

                    // 6. 提示用户（托盘气泡通知）
                    notifyIcon.ShowBalloonTip(2000, "截屏成功", $"已保存到：{fullPath}", ToolTipIcon.Info);
                }
            }
            catch (Exception ex)
            {
                // 出错时提示
                MessageBox.Show($"保存失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region 关闭窗口时事件
        /// <summary>
        /// 关闭窗口时事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            UnregisterHotKey(Handle, HOTKEY_ID); // 取消热键注册，避免程序退出后热键仍被占用
        }
        #endregion

        #region 窗口发生变化时事件
        /// <summary>
        /// 窗口发生变化时事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                Hide(); // 隐藏窗口
                notifyIcon.Visible = true; // 显示托盘图标
            }
        }
        #endregion

        #region 双击托盘图片事件
        /// <summary>
        /// 双击托盘图片事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show(); // 显示窗口
            WindowState = FormWindowState.Normal; // 恢复正常大小
        }

        private void tsmiExit_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要退出程序吗？", "退出", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                this.Close();
                Application.Exit();
            }
        } 
        #endregion
    }
}
